\defmodule {TallyHistogram}

This class is an extension of \class{Tally} which gives a more detailed view
of the observations statistics. The individual observations are assumed to
fall into different bins (boxes) of equal width on an interval.
The total number of observations falling into the bins are kept in an array
of counters. This is useful, for example, if one wish to build a histogram
from the observations. One must access the array of bin counters
to compute quantities not supported by the methods in \class{Tally}.

\emph{Never add or remove observations directly} on the array of
bin counters because this would put the \class{Tally} counters in an
inconsistent state.


\bigskip\hrule

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{code}
\begin{hide}
/*
 * Class:        TallyHistogram
 * Description:  Histogram of a tally
 * Environment:  Java
 * Software:     SSJ
 * Copyright (C) 2001  Pierre L'Ecuyer and Universite de Montreal
 * Organization: DIRO, Universite de Montreal
 * @author       Richard Simard
 * @since        January 2011

 * SSJ is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License (GPL) as published by the
 * Free Software Foundation, either version 3 of the License, or
 * any later version.

 * SSJ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * A copy of the GNU General Public License is available at
   <a href="http://www.gnu.org/licenses">GPL licence site</a>.
 */
\end{hide}
package umontreal.iro.lecuyer.stat;\begin{hide}
import java.util.logging.Level;
import java.util.logging.Logger;
import umontreal.iro.lecuyer.util.PrintfFormat;
\end{hide}


public class TallyHistogram extends Tally \begin{hide} {
   private int[] co;         // counter: num of values in bin[i]
   private int numBins;      // number of bins
   private double m_h;       // width of 1 bin
   private double m_a;       // left boundary of first bin
   private double m_b;       // right boundary of last bin
   private Logger log = Logger.getLogger ("umontreal.iro.lecuyer.stat");
\end{hide}
\end{code}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection* {Constructors}
\begin{code}

   public TallyHistogram(double a, double b, int s) \begin{hide} {
      super();
      init (a, b, s);
   }\end{hide}
\end{code}
\begin{tabb}  Constructs a \texttt{TallyHistogram} statistical probe.
Divide the interval $[a,b]$ into $s$ bins of equal width and initializes
a counter to 0 for each bin. Whenever an observation falls into a bin,
the bin counter is increased by 1. There are two extra bins (and counters)
that count the number of observations $x$ that fall outside the interval
$[a,b]$: one for those $x< a$, and the other for  those $x > b$.
\end{tabb}
\begin{htmlonly}
   \param{a}{left boundary of interval}
   \param{b}{right boundary of interval}
   \param{s}{number of bins}
\end{htmlonly}
\begin{code}

   public TallyHistogram (String name, double a, double b, int s) \begin{hide} {
      super (name);
      init (a, b, s);
   }\end{hide}
\end{code}
\begin{tabb} Constructs a new \texttt{TallyHistogram} statistical probe with
name \texttt{name}.
\end{tabb}
\begin{htmlonly}
   \param{name}{the name of the tally.}
   \param{a}{left boundary of interval}
   \param{b}{right boundary of interval}
   \param{s}{number of bins}
\end{htmlonly}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection* {Methods}
\begin{code}

   public void init (double a, double b, int s) \begin{hide} {
      /* The counters co[1] to co[s] contains the number of observations
         falling in the interval [a, b].
         co[0] is the number of observations < a,
         and co[s+1] is the number of observations > b.
      */

      super.init();
      if (b <= a)
         throw new IllegalArgumentException ("   b <= a");
      co = new int[s + 2];
      numBins = s;
      m_h = (b - a) / s;
      m_a = a;
      m_b = b;
      for (int i = 0; i <= s + 1; i++)
         co[i] = 0;
   } \end{hide}
\end{code}
\begin{tabb}  Initializes this object.
Divide the interval $[a,b]$ into $s$ bins of equal width and initializes
all counters to 0.
\end{tabb}
\begin{htmlonly}
   \param{s}{number of bins}
   \param{a}{left boundary of interval}
   \param{b}{right boundary of interval}
\end{htmlonly}
\begin{code}

   public void add (double x) \begin{hide} {
      super.add(x);
      if (x < m_a)
        ++co[0];
      else if (x > m_b)
        ++co[1 + numBins];
      else {
         int i = 1 + (int) ((x - m_a) / m_h);
         ++co[i];
      }
   }\end{hide}
\end{code}
\begin{tabb} Gives a new observation $x$ to the statistical collectors.
Increases by 1 the bin counter in which value $x$ falls.
Values that fall outside the interval $[a,b]$ are added in extra bin
counter bin[0] if $x < a$, and in bin[$s+1$] if $x > b$.
\end{tabb}
\begin{htmlonly}
   \param{x}{observation value}
\end{htmlonly}
\begin{code}

   public int[] getCounters() \begin{hide} {
      return co;
   }\end{hide}
\end{code}
\begin{tabb} Returns the bin counters. Each counter contains the number of
observations that fell in its corresponding bin.
The counters bin[$i$], $i=1, 2, \ldots, s$ contain the number of observations
that fell in each subinterval of $[a,b]$. Values that fell outside the interval
$[a,b]$ were added in extra bin counter bin[0] if $x < a$, and in bin[$s+1$]
if $x > b$. There are thus $s+2$ counters.
\end{tabb}
\begin{htmlonly}
   \return{the array of counters}
\end{htmlonly}
\begin{code}

   public int getNumBins() \begin{hide} {
      return numBins;
   }\end{hide}
\end{code}
\begin{tabb} Returns the number of bins $s$ dividing the interval $[a,b]$.
Does not count the two extra bins for the values of $x<a$ or $x>b$.
\end{tabb}
\begin{htmlonly}
   \return{the number of bins}
\end{htmlonly}
\begin{code}

   public double getA() \begin{hide} {
      return m_a;
   }\end{hide}
\end{code}
\begin{tabb}  Returns the left boundary $a$ of interval $[a,b]$.
\end{tabb}
\begin{htmlonly}
   \return{left boundary of interval}
\end{htmlonly}
\begin{code}

   public double getB() \begin{hide} {
      return m_b;
   }\end{hide}
\end{code}
\begin{tabb}  Returns the right boundary $b$ of interval $[a,b]$.
\end{tabb}
\begin{htmlonly}
   \return{right boundary of interval}
\end{htmlonly}
\begin{code}

   public TallyHistogram clone()\begin{hide} {
      TallyHistogram image = (TallyHistogram)super.clone();
      int[] coco = new int[2 + numBins];
      System.arraycopy (co, 0, coco, 0, 2 + numBins);
      image.co = coco;
      image.m_h = m_h;
      image.m_a = m_a;
      image.m_b = m_b;
      image.numBins = numBins;
      return image;
   }\end{hide}
\end{code}
\begin{tabb} Clones this object and the array which stores the counters.
\end{tabb}
\begin{code}

   public String toString()\begin{hide} {
      StringBuffer sb = new StringBuffer ();
      sb.append ("---------------------------------------" +
                PrintfFormat.NEWLINE);
      sb.append (name + PrintfFormat.NEWLINE);
      sb.append ("Interval = [ " + m_a + ", " + m_b + " ]" +
                 PrintfFormat.NEWLINE);
      sb.append ("Number of bins = " + numBins + " + 2" + PrintfFormat.NEWLINE);
      sb.append (PrintfFormat.NEWLINE + "Counters = {" +
                 PrintfFormat.NEWLINE);
      sb.append ("   (-inf, " + PrintfFormat.f(6, 3, m_a)
                 + ")    " + co[0] + PrintfFormat.NEWLINE);
      for (int i = 1; i <= numBins; i++) {
         double a = m_a + (i-1)*m_h;
         double b = m_a + i*m_h;
         sb.append ("   (" +
            PrintfFormat.f(6, 3, a) + ", " +
            PrintfFormat.f(6, 3, b) + ")    " + co[i] +
                 PrintfFormat.NEWLINE);
      }
      sb.append ("   (" + PrintfFormat.f(6, 3, m_b)
                 + ", inf)    " + co[numBins + 1] +
                 PrintfFormat.NEWLINE);
      sb.append ("}" + PrintfFormat.NEWLINE);
      return sb.toString();
   }\end{hide}
\end{code}
\begin{tabb} Returns the bin counters as a \texttt{String}.
\end{tabb}
\begin{code}\begin{hide}
}\end{hide}
\end{code}
